<!DOCTYPE html>
<html>

<head>
    <title>StackBarChart</title>
    <script src="d3.min.js"></script>
</head>

<body>
    <svg width="1600" height="800" id="mainsvg" class="svgs" style='display: block; margin: 0 auto;'></svg>
    <script>
        const svg = d3.select('#mainsvg');
        const width = +svg.attr('width');
        const height = +svg.attr('height');
        const margin = { top: 120, right: 200, bottom: 100, left: 200 };
        const innerWidth = width - margin.left - margin.right;
        const innerHeight = height - margin.top - margin.bottom;
        const g = svg.append('g').attr('id', 'maingroup')
            .attr('transform', `translate(${margin.left}, ${margin.top})`);
        const naiveData = [
            { month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400 },
            { month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400 },
            { month: new Date(2015, 2, 1), apples: 640, bananas: 960, cherries: 640, dates: 400 },
            { month: new Date(2015, 3, 1), apples: 320, bananas: 480, cherries: 640, dates: 400 }
        ];
        const naiveKeys = ["apples", "bananas", "cherries", "dates"];

        [
            [[   0, 3840], [   0, 1600], [   0,  640], [   0,  320]], // apples
            [[3840, 5760], [1600, 3040], [ 640, 1600], [ 320,  800]], // bananas
            [[5760, 6720], [3040, 4000], [1600, 2240], [ 800, 1440]], // cherries
            [[6720, 7120], [4000, 4400], [2240, 2640], [1440, 1840]], // dates
        ]

        var naiveStack = d3.stack()
        .keys(naiveKeys)
        .order(d3.stackOrderNone)(naiveData);

        const xValue = d => d.month;

        const yScale = d3.scaleLinear()
        .domain([0, d3.max(naiveStack, d => d3.max(d, subd => subd[1]))])
        .range([innerHeight, 0]).nice();

        const xScale = d3.scaleBand()
        .domain(naiveData.map(d => xValue(d)))
        .range([0, innerWidth])
        .padding(0.5);

        const color = d3.scaleOrdinal()
        .domain(naiveKeys)
        .range(d3.schemeSet3)

        // start to do data-join; 
        g.selectAll('.datagroup').data(naiveStack).join('g')
        .attr('class', 'datagroup')
        .attr('fill', d => color(d.key))
        .selectAll('.datarect').data(d => d).join('rect')
        .attr('class', 'datarect')
        .attr('y', d => yScale(d[1]))
        .attr('x', d => xScale(xValue(d.data)))
        .attr('height', d => yScale(d[0]) - yScale(d[1]))
        .attr('width', xScale.bandwidth());

        // drawing axes;
        let yAxis = d3.axisLeft(yScale);
        let xAxis = d3.axisBottom(xScale).tickFormat(d3.timeFormat('%b-%d'));
        g.append('g').attr('id', 'yaxis').call(yAxis);
        g.append('g').attr('id', 'xaxis').call(xAxis).attr('transform', `translate(0, ${innerHeight})`);
        d3.selectAll('.tick text').attr('font-size', '2em');
        d3.selectAll('#xaxis text').attr('y', '10')
    </script>
</body>

</html>